package com.app.couponsharelife.ui.view

import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.Interpolator
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.Scroller
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.manager.LifecycleListener
import com.bumptech.glide.request.RequestOptions
import com.app.couponsharelife.R
import com.app.couponsharelife.utils.AppUtils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit

/**
 * Created by guluwa on 2018/3/24.
 */

class BannerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) :
        FrameLayout(context, attrs, defStyle), ViewPager.OnPageChangeListener, LifecycleListener {

    var imageUrls: MutableList<Any> = ArrayList()

    private var imageViews: MutableList<View> = ArrayList()

    lateinit var mViewPager: BannerViewPager

    private lateinit var mBannerIndicator: BannerIndicator

    private var count = 0

    var currentItem = 0

    var placeHolderType = 1

    var cornerRadius = 0

    var needIndicator = true

    var isHome = false

    private var isAutoScroll = true

    private var disposable: Disposable? = null

    var onPageChangeListeners = mutableListOf<ViewPager.OnPageChangeListener>()

    var onPageClickListener: OnPageClickListener? = null

    var onPageSelectListener: OnPageSelectListener? = null

    init {
        val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.BannerView, defStyle, 0)
        placeHolderType = typedArray.getInt(R.styleable.BannerView_placeHolderType, 1)
        cornerRadius = typedArray.getInt(R.styleable.BannerView_bannerCornerRadius, 0)
        needIndicator = typedArray.getBoolean(R.styleable.BannerView_needIndicator, true)
        isHome = typedArray.getBoolean(R.styleable.BannerView_isHome, false)
        initView()
    }

    private fun initView() {
        val view = if (placeHolderType == 3)
            LayoutInflater.from(context).inflate(R.layout.banner_layout_place_holder, this, true)
        else
            LayoutInflater.from(context).inflate(R.layout.banner_layout, this, true)
        mViewPager = view.findViewById(R.id.mViewPager)
        if (needIndicator) {
            mBannerIndicator = view.findViewById(R.id.mBannerIndicator)
            /*if (isHome && placeHolderType != 3) {
                val layoutParams = ConstraintLayout.LayoutParams(
                        ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)
                layoutParams.bottomToBottom = R.id.mGuideLineBottom
                layoutParams.startToStart = R.id.mRootContainer
                layoutParams.endToEnd = R.id.mRootContainer
                mBannerIndicator.layoutParams = layoutParams
            }*/
        }
        initViewPagerScroll()
    }

    private fun initViewPagerScroll() {
        try {
            val scrollerField = ViewPager::class.java.getDeclaredField("mScroller")
            scrollerField.isAccessible = true
            val interpolator = ViewPager::class.java.getDeclaredField("sInterpolator")
            interpolator.isAccessible = true

            val scroller = object : Scroller(context, interpolator.get(null) as Interpolator) {
                override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) {
                    super.startScroll(startX, startY, dx, dy, 800)
                }

                override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int) {
                    super.startScroll(startX, startY, dx, dy, 800)
                }
            }
            scrollerField.set(mViewPager, scroller)
        } catch (e: NoSuchFieldException) {
            // Do nothing.
        } catch (e: IllegalAccessException) {
            // Do nothing.
        }
    }

    fun start(list: List<Any>) {
        initImageUrl(list)
        initImageView()
        setAdapter()
    }

    private fun initImageUrl(list: List<Any>) {
        imageUrls.clear()
        imageUrls.addAll(list)
        count = imageUrls.size
    }

    private fun initImageView() {
        if (imageUrls.isEmpty()) {
            println("no pic 。。。。")
            return
        }
        for (i in 0..count + 1) {
            val imageView = ImageView(context)
            imageView.scaleType = ImageView.ScaleType.CENTER_CROP
            if (placeHolderType != 3){
                imageView.setPadding(16,0,16,0)
            }
            var url = when (i) {
                0 -> imageUrls[count - 1]
                count + 1 -> imageUrls[0]
                else -> imageUrls[i - 1]
            }
            imageViews.add(imageView)
            if (url is Int) {
                if (cornerRadius != 0) {
                    Glide.with(context)
                            .load(url)
                            .apply(RequestOptions().placeholder(
                                    when (placeHolderType) {
                                        1 -> R.drawable.ic_app_place_holder1
                                        2 -> R.drawable.ic_app_place_holder2
                                        else -> R.drawable.ic_app_place_holder3
                                    })
                                    .transform(RoundedCorners( AppUtils.dip2px(context, cornerRadius.toFloat()))))
                            .into(imageView)
                } else {
                    Glide.with(context)
                            .load(url)
                            .apply(RequestOptions().placeholder(
                                    when (placeHolderType) {
                                        1 -> R.drawable.ic_app_place_holder1
                                        2 -> R.drawable.ic_app_place_holder2
                                        else -> R.drawable.ic_app_place_holder3
                                    })).into(imageView)
                }
            } else {
                if (cornerRadius != 0) {
                    Glide.with(context).load((url as String).replace(" ", ""))
                            .apply(RequestOptions().placeholder(
                                    when (placeHolderType) {
                                        1 -> R.drawable.ic_app_place_holder1
                                        2 -> R.drawable.ic_app_place_holder2
                                        else -> R.drawable.ic_app_place_holder3
                                    })
                                    .transform(RoundedCorners( AppUtils.dip2px(context, cornerRadius.toFloat()))))
                            .into(imageView)
                } else {
                    Glide.with(context).load((url as String).replace(" ", ""))
                            .apply(RequestOptions().placeholder(
                                    when (placeHolderType) {
                                        1 -> R.drawable.ic_app_place_holder1
                                        2 -> R.drawable.ic_app_place_holder2
                                        else -> R.drawable.ic_app_place_holder3
                                    })).into(imageView)
                }
            }
            imageView.setOnClickListener {
                onPageClickListener?.click(imageViews.indexOf(imageView) - 1)
            }
        }
    }

    private fun setAdapter() {
        mViewPager.addOnPageChangeListener(this)
        mViewPager.adapter = BannerAdapter()
        if (placeHolderType != 3) {
            mViewPager.pageMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, resources.displayMetrics).toInt()
        }
        mViewPager.currentItem = 1
        mViewPager.offscreenPageLimit = imageViews.size - 1
        currentItem = 1
        if (imageUrls.size != 1) {
            mViewPager.setScrollable(true)
            if (needIndicator) {
                mBannerIndicator.visibility = View.VISIBLE
                mBannerIndicator.initIndicator(imageUrls.size)
                mBannerIndicator.bindViewPager(this)
            }
        } else {
            mViewPager.setScrollable(false)
            mBannerIndicator.visibility = View.GONE
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.action
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
                || action == MotionEvent.ACTION_OUTSIDE) {
            isAutoScroll = true
        } else if (action == MotionEvent.ACTION_DOWN) {
            isAutoScroll = false
        }
        return super.dispatchTouchEvent(ev)
    }

    override fun onPageScrollStateChanged(state: Int) {
        when (state) {
            0//No operation
            -> if (currentItem == 0) {
                mViewPager.setCurrentItem(count, false)
            } else if (currentItem == count + 1) {
                mViewPager.setCurrentItem(1, false)
            }
            1//start Sliding
            -> if (currentItem == count + 1) {
                mViewPager.setCurrentItem(1, false)
            } else if (currentItem == 0) {
                mViewPager.setCurrentItem(count, false)
            }
            2//end Sliding
            -> {
            }
        }
        for (listener in onPageChangeListeners)
            listener.onPageScrollStateChanged(state)
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        for (listener in onPageChangeListeners)
            listener.onPageScrolled(position, positionOffset, positionOffsetPixels)
    }

    override fun onPageSelected(position: Int) {
        currentItem = position
        for (listener in onPageChangeListeners)
            listener.onPageSelected(position)
        onPageSelectListener?.select(
                when (position) {
                    count + 1 -> 0
                    0 -> count - 1
                    else -> position - 1
                }
        )
    }

    override fun onStart() {
        isAutoScroll = true
        bindProgressQuery()
        println("onStart")
    }

    override fun onStop() {
        isAutoScroll = false
        println("onStop")
    }

    override fun onDestroy() {
        unbindProgressQuery()
        println("onDestroy")
    }

    /**
     * 开始轮询
     */
    private fun bindProgressQuery() {
        if (disposable == null) {
            disposable = Observable.interval(3000, 3000, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        if (count > 1 && isAutoScroll) {
                            currentItem = currentItem % (count + 1) + 1
                            if (currentItem == 1) {
                                mViewPager.setCurrentItem(currentItem, false)
                            } else {
                                mViewPager.currentItem = currentItem
                            }
                        }
                    }
        }
    }

    /**
     * 结束轮询
     */
    private fun unbindProgressQuery() {
        if (disposable != null && !disposable!!.isDisposed) {
            disposable!!.dispose()
            disposable = null
        }
    }

    fun bindListener(listener: ViewPager.OnPageChangeListener) {
        onPageChangeListeners.add(listener)
    }

    fun bindOnPageClickListener(listener: OnPageClickListener) {
        onPageClickListener = listener
    }

    fun bindPageSelectListener(listener: OnPageSelectListener) {
        onPageSelectListener = listener
    }

    private inner class BannerAdapter : PagerAdapter() {

        override fun isViewFromObject(view: View, arg1: Any): Boolean {
            return view == arg1
        }

        override fun getCount(): Int {
            return imageViews.size
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            container.addView(imageViews[position])
            return imageViews[position]
        }

        override fun destroyItem(container: ViewGroup, position: Int, arg1: Any) {
            container.removeView(arg1 as View)
        }
    }

    interface OnPageClickListener {
        fun click(position: Int)
    }

    interface OnPageSelectListener {
        fun select(position: Int)
    }
}